/**
 * WebSocketResponse.js
 * @author Ulyan Sobin
 * @description WebSocketResponse class
 */

"use strict";

const { WebResponse } = require("../WebResponse");
const WebSocket = require("ws");

class WebSocketResponse extends WebResponse {
	
	/** @type {WebSocket} */
	origin;

	/**
	 * Constructor of `WebSocketResponse`
	 * @param {WebSocket} socket
	 * @param {{ 
		open: WebSocket.OpenEvent, 
		message: WebSocket.MessageEvent, 
		close: WebSocket.CloseEvent, 
		error: WebSocket.ErrorEvent 
	  }} listeners
	 */
	constructor (socket, listeners) {
		if (!(socket instanceof WebSocket))
			throw new Error("\'socket\' must be instance of \'WebSocket\'");
		super();
		this.origin = socket;
		if (typeof(listeners) == "object")
			this.syncListeners(listeners);
	}

	/**
	 * @private
	 * @param {Object} listeners
	 */
	syncListeners(listeners) {
		if (typeof(listeners.open) == "function")
			this.origin.onopen = listeners.open;
		if (typeof(listeners.message) == "function")
			this.origin.onmessage = listeners.message;
		if (typeof(listeners.close) == "function")
			this.origin.onclose = listeners.close;
		if (typeof(listeners.error) == "function")
			this.origin.onerror = listeners.error;
	}

	/**
	 * Send data
	 * @param {any} data
	 */
	send(data) {
		return new Promise((resolve, reject) => {
			try {
				this.origin.send(data, (err) => {
					if (err) reject(err);
					else resolve();
				});
			} catch (err) {
				reject(err);
			}
		});
	}

	/**
	 * Close the connect
	 * @param {number} code 
	 * @param {string} reason 
	 */
	close(code, reason) {
		if (typeof(code) != "number") code = 1000;
		if (typeof(reason) != "string") reason = "";
		this.origin.close(code, reason);
	}
}

module.exports.WebSocketResponse = WebSocketResponse;